package com.demo;

import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.widget.Button;
import com.demo.activity.VideoActivity;
import com.demo.domain.Contact;
import com.demo.fragment.EditForm;
import com.demo.fragment.PreviewForm;
import junit.framework.Assert;

public class VideoActivityTest extends ActivityInstrumentationTestCase2<VideoActivity> {

    final Contact contact = new Contact("testFirstName", "testLastName", "1234567890", "qwe@qwe.com", null);

    /**
     * Check test runner. Empty test
     */
    @SmallTest
    public void testPreconditions() {
    }

    /**
     * Test basic startup/shutdown of Application
     */
    @MediumTest
    public void testSimpleCreateTest() {
        final VideoActivity activity = getActivity();
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                Assert.assertNotNull(activity);
                activity.finish();
            }
        });
    }

    public VideoActivityTest() {
        super(VideoActivity.class);
    }

    @MediumTest
    public void testFillingFields() throws Exception {
        final VideoActivity activity = getActivity();
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {

                activity.fillEditForm(contact);

                Contact testContact = new Contact();
                activity.fillContactData(testContact);

                Assert.assertEquals(contact, testContact);
                activity.finish();
            }
        });
    }

    @MediumTest
    public void testFragmentReplace() throws Exception {
        final VideoActivity activity = getActivity();
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                // check for EditForm fragment was added to activity
                Fragment fragment = activity.getFragmentManager().findFragmentById(R.id.contact_edit_fragment);
                Assert.assertEquals(EditForm.class, fragment.getClass());

                // invoke apply button click
                Button button = (Button) activity.findViewById(R.id.apply_button);
                button.performClick();
                // perform replace fragments
                activity.getFragmentManager().executePendingTransactions();

                // check if EditForm is replaced by PreviewForm
                fragment = activity.getFragmentManager().findFragmentById(R.id.contact_edit_fragment);
                Assert.assertEquals(PreviewForm.class, fragment.getClass());

                // invoke back button click
                button = (Button) activity.findViewById(R.id.back_button);
                button.performClick();
                activity.getFragmentManager().executePendingTransactions();

                // check if PreviewForm is replaced by EditForm
                fragment = activity.getFragmentManager().findFragmentById(R.id.contact_edit_fragment);
                Assert.assertEquals(EditForm.class, fragment.getClass());

                activity.finish();
            }
        });
    }

    /**
     * Test activity lifecycle saving data
     * @throws Exception
     */
    @MediumTest
    public void testContactBundleTransfer() throws Exception {
        final VideoActivity activity = getActivity();
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                // fill edit form fields
                activity.fillContactData(contact);

                // click Apply button
                Button button = (Button) activity.findViewById(R.id.apply_button);
                button.performClick();
                activity.getFragmentManager().executePendingTransactions();

                // click Back button
                button = (Button) activity.findViewById(R.id.back_button);
                button.performClick();
                activity.getFragmentManager().executePendingTransactions();

                // retrieve data from fields
                Contact contact2 = new Contact();
                activity.fillContactData(contact2);

                // check if contact and contact2 is equals
                Assert.assertEquals(contact, contact2);

                activity.finish();
            }
        });
    }

    /**
     * Test data restoration after activity pause
     *
     * @throws Exception
     */
    @MediumTest
    public void testOnPauseBundleTransfer() throws Exception {

        Intent intent = new Intent();
        intent.putExtra(Contact.CONTACT, contact);

        setActivityIntent(intent);

        final VideoActivity activity = getActivity();

        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                Contact contact2 = new Contact();
                activity.fillContactData(contact2);

                Assert.assertEquals(contact, contact2);

                activity.finish();
            }
        });
    }

    /**
     * Test saving activity edit state. <br/>
     * <ul>
     * <li>Start activity. Test if contactEditFragment class is EditForm.class.</li>
     * <li>Stop activity with saving onSaveInstanceState bundle</li>
     * <li>Start new VideoActivity with saving bundle</li>
     * <li>Check if contactEditFragment class is EditForm.class.</li>
     * </ul>
     *
     * @throws Exception
     */
    @MediumTest
    public void testEditStateRestore() throws Exception {

        final VideoActivity activity = getActivity();
        Assert.assertNotNull(activity);

        final Bundle bundle = new Bundle();

        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                Fragment fragment = activity.getFragmentManager().findFragmentById(R.id.contact_edit_fragment);

                assertNotNull(fragment);
                assertEquals(EditForm.class, fragment.getClass());

                getInstrumentation().callActivityOnSaveInstanceState(activity, bundle);
                getInstrumentation().callActivityOnPause(activity);
                getInstrumentation().callActivityOnStop(activity);

                getInstrumentation().callActivityOnCreate(activity, bundle);
                getInstrumentation().callActivityOnStart(activity);
                getInstrumentation().callActivityOnResume(activity);

                fragment = activity.getFragmentManager().findFragmentById(R.id.contact_edit_fragment);
                assertNotNull(fragment);
                assertEquals(EditForm.class, fragment.getClass());
            }
        });

    }

    /**
     * Test saving activity preview state. <br/>
     * <ul>
     * <li>Start activity. Test if contactEditFragment class is EditForm.class.</li>
     * <li>Click on ApplyButton.</li>
     * <li>Stop activity with saving onSaveInstanceState bundle</li>
     * <li>Start new VideoActivity with saving bundle</li>
     * <li>Check if contactEditFragment class is EditForm.class.</li>
     * </ul>
     *
     * @throws Exception
     */
    @MediumTest
    public void testPreviewStateRestore() throws Exception {

        final VideoActivity activity = getActivity();
        Assert.assertNotNull(activity);

        final Bundle bundle = new Bundle();

        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                Fragment fragment = activity.getFragmentManager().findFragmentById(R.id.contact_edit_fragment);

                assertNotNull(fragment);
                assertEquals(EditForm.class, fragment.getClass());

                Button applyButton = (Button) activity.findViewById(R.id.apply_button);

                assertNotNull(applyButton);

                applyButton.performClick();

                getInstrumentation().callActivityOnSaveInstanceState(activity, bundle);
                getInstrumentation().callActivityOnPause(activity);
                getInstrumentation().callActivityOnStop(activity);

                getInstrumentation().callActivityOnCreate(activity, bundle);
                getInstrumentation().callActivityOnStart(activity);
                getInstrumentation().callActivityOnResume(activity);

                fragment = activity.getFragmentManager().findFragmentById(R.id.contact_edit_fragment);
                assertNotNull(fragment);
                assertEquals(PreviewForm.class, fragment.getClass());
            }
        });

    }
}
